import { 
  CacheStatus,
  type ParsedEntry, 
  type PerformanceMetrics, 
  type ComparisonResult, 
  type HarFile, 
  ResourceType} from '../types/har';

/**
 * 计算性能指标
 */
export function calculateMetrics(entries: ParsedEntry[]): PerformanceMetrics {
  if (entries.length === 0) {
    return {
      totalTime: 0,
      averageResponseTime: 0,
      maxResponseTime: 0,
      minResponseTime: 0,
      p95ResponseTime: 0,
      totalRequests: 0,
      totalSize: 0,
      averageSize: 0,
      cacheHitRate: 0,
      averageDnsTime: 0,
      averageConnectTime: 0,
      averageSslTime: 0,
      averageTtfb: 0,
      averageRedirectTime: 0,
      averageDownloadTime: 0,
      resourceTypeStats: {} as Record<ResourceType, any>
    };
  }

  const responseTimes = entries.map(entry => entry.time);
  const sizes = entries.map(entry => entry.size);
  const dnsTimes = entries.map(entry => entry.timings.dns);
  const connectTimes = entries.map(entry => entry.timings.connect);
  const sslTimes = entries.map(entry => entry.timings.ssl);
  const ttfbTimes = entries.map(entry => entry.timings.wait);
  const redirectTimes = entries.map(entry => entry.timings.send);
  const downloadTimes = entries.map(entry => entry.timings.receive);
  
  // 计算缓存命中率
  const cacheHits = entries.filter(entry => entry.cacheStatus === CacheStatus.HIT).length;
  const cacheHitRate = (cacheHits / entries.length) * 100;

  // 按资源类型分组统计
  const resourceTypeStats = entries.reduce((acc, entry) => {
    const type = entry.resourceType;
    if (!acc[type]) {
      acc[type] = { count: 0, totalSize: 0, averageTime: 0 };
    }
    acc[type].count++;
    acc[type].totalSize += entry.size;
    acc[type].averageTime += entry.time;
    return acc;
  }, {} as Record<ResourceType, { count: number; totalSize: number; averageTime: number }>);

  // 计算平均时间
  Object.keys(resourceTypeStats).forEach(type => {
    const stats = resourceTypeStats[type as ResourceType];
    stats.averageTime = stats.averageTime / stats.count;
  });

  // 计算 95% 分位数
  const sortedTimes = [...responseTimes].sort((a, b) => a - b);
  const p95Index = Math.ceil(sortedTimes.length * 0.95) - 1;
  const p95ResponseTime = sortedTimes[p95Index] || 0;

  return {
    totalTime: Math.max(...responseTimes),
    averageResponseTime: responseTimes.reduce((sum, time) => sum + time, 0) / responseTimes.length,
    maxResponseTime: Math.max(...responseTimes),
    minResponseTime: Math.min(...responseTimes),
    p95ResponseTime,
    totalRequests: entries.length,
    totalSize: sizes.reduce((sum, size) => sum + size, 0),
    averageSize: sizes.reduce((sum, size) => sum + size, 0) / sizes.length,
    cacheHitRate,
    averageDnsTime: dnsTimes.reduce((sum, time) => sum + time, 0) / dnsTimes.length,
    averageConnectTime: connectTimes.reduce((sum, time) => sum + time, 0) / connectTimes.length,
    averageSslTime: sslTimes.reduce((sum, time) => sum + time, 0) / sslTimes.length,
    averageTtfb: ttfbTimes.reduce((sum, time) => sum + time, 0) / ttfbTimes.length,
    averageRedirectTime: redirectTimes.reduce((sum, time) => sum + time, 0) / redirectTimes.length,
    averageDownloadTime: downloadTimes.reduce((sum, time) => sum + time, 0) / downloadTimes.length,
    resourceTypeStats
  };
}

/**
 * 对比两个 HAR 文件
 */
export function compareHarFiles(
  baselineFile: HarFile, 
  targetFile: HarFile
): ComparisonResult {
  const baselineMetrics = calculateMetrics(baselineFile.parsedData || []);
  const targetMetrics = calculateMetrics(targetFile.parsedData || []);

  // 计算差异百分比
  const timeImprovement = calculateImprovement(
    baselineMetrics.averageResponseTime, 
    targetMetrics.averageResponseTime
  );
  
  const sizeReduction = calculateImprovement(
    baselineMetrics.totalSize, 
    targetMetrics.totalSize
  );
  
  const requestReduction = calculateImprovement(
    baselineMetrics.totalRequests, 
    targetMetrics.totalRequests
  );
  
  const cacheImprovement = targetMetrics.cacheHitRate - baselineMetrics.cacheHitRate;

  // 生成关键洞察
  const keyInsights = generateKeyInsights(baselineMetrics, targetMetrics);
  
  // 生成优化建议
  const recommendations = generateRecommendations(baselineMetrics, targetMetrics);

  // 计算总体改善评分 (0-100)
  const overallImprovement = calculateOverallImprovement({
    timeImprovement,
    sizeReduction,
    requestReduction,
    cacheImprovement
  });

  return {
    baseline: {
      file: baselineFile,
      metrics: baselineMetrics
    },
    target: {
      file: targetFile,
      metrics: targetMetrics
    },
    differences: {
      timeImprovement,
      sizeReduction,
      requestReduction,
      cacheImprovement
    },
    summary: {
      overallImprovement,
      keyInsights,
      recommendations
    }
  };
}

/**
 * 计算改善百分比
 */
function calculateImprovement(baseline: number, target: number): number {
  if (baseline === 0) return 0;
  return ((baseline - target) / baseline) * 100;
}

/**
 * 生成关键洞察
 */
function generateKeyInsights(
  baseline: PerformanceMetrics, 
  target: PerformanceMetrics
): string[] {
  const insights: string[] = [];

  if (target.averageResponseTime < baseline.averageResponseTime) {
    const improvement = ((baseline.averageResponseTime - target.averageResponseTime) / baseline.averageResponseTime) * 100;
    insights.push(`平均响应时间改善了 ${improvement.toFixed(1)}%`);
  }

  if (target.totalSize < baseline.totalSize) {
    const reduction = ((baseline.totalSize - target.totalSize) / baseline.totalSize) * 100;
    insights.push(`总资源大小减少了 ${reduction.toFixed(1)}%`);
  }

  if (target.cacheHitRate > baseline.cacheHitRate) {
    const improvement = target.cacheHitRate - baseline.cacheHitRate;
    insights.push(`缓存命中率提升了 ${improvement.toFixed(1)}%`);
  }

  if (target.totalRequests < baseline.totalRequests) {
    const reduction = ((baseline.totalRequests - target.totalRequests) / baseline.totalRequests) * 100;
    insights.push(`请求数量减少了 ${reduction.toFixed(1)}%`);
  }

  return insights;
}

/**
 * 生成优化建议
 */
function generateRecommendations(
  baseline: PerformanceMetrics, 
  target: PerformanceMetrics
): string[] {
  const recommendations: string[] = [];

  if (target.cacheHitRate < 50) {
    recommendations.push('考虑增加缓存策略，提高缓存命中率');
  }

  if (target.averageSslTime > 100) {
    recommendations.push('SSL 握手时间较长，考虑优化证书配置');
  }

  if (target.averageDnsTime > 50) {
    recommendations.push('DNS 查询时间较长，考虑使用 DNS 预解析');
  }

  if (target.resourceTypeStats[ResourceType.IMAGE]?.totalSize > target.totalSize * 0.3) {
    recommendations.push('图片资源占用较大，考虑图片压缩或使用 WebP 格式');
  }

  if (target.resourceTypeStats[ResourceType.SCRIPT]?.totalSize > target.totalSize * 0.2) {
    recommendations.push('JavaScript 资源较大，考虑代码分割和懒加载');
  }

  return recommendations;
}

/**
 * 计算总体改善评分
 */
function calculateOverallImprovement(differences: {
  timeImprovement: number;
  sizeReduction: number;
  requestReduction: number;
  cacheImprovement: number;
}): number {
  const { timeImprovement, sizeReduction, requestReduction, cacheImprovement } = differences;
  
  // 权重分配：时间 40%，大小 30%，请求数 20%，缓存 10%
  const weightedScore = 
    (Math.max(0, timeImprovement) * 0.4) +
    (Math.max(0, sizeReduction) * 0.3) +
    (Math.max(0, requestReduction) * 0.2) +
    (Math.max(0, cacheImprovement) * 0.1);
  
  return Math.min(100, Math.max(0, weightedScore));
}

